<!-- 
在 Vue 3 中，自定义指令是一种扩展 Vue 功能的方式，允许开发者通过指令实现特定的 DOM 操作或行为。与内置指令（如  `v-if` 、 `v-for` 、 `v-model`  等）类似，自定义指令可以在模板中使用，以便在特定条件下对元素应用特定的逻辑。以下是关于 Vue 3 中自定义指令的说明总结：

  1. 创建自定义指令
  在 Vue 3 中，可以通过  `app.directive`  方法来注册自定义指令。自定义指令需要定义一个钩子函数，用于处理指令的逻辑。
   示例：注册自定义指令
  import { createApp } from 'vue';
  const app = createApp({});

  // 定义一个自定义指令 `v-focus`
  app.directive('focus', {
    // 当被绑定的元素插入到 DOM 中时
    mounted(el) {
      el.focus(); // 使元素获得焦点
    }
  });

  app.mount('#app');
  2. 使用自定义指令
  注册自定义指令后，可以在模板中使用它。使用方式与内置指令相同，只需在元素上添加  `v-指令名`  的形式。

   示例：使用自定义指令
  vue
  <template>
    <input v-focus />
  </template>
  3. 自定义指令的钩子函数
  自定义指令可以定义多个钩子函数，以处理不同的生命周期事件：
  -  `created` ：指令被绑定到元素时调用。
  -  `beforeMount` ：在元素被插入到 DOM 之前调用。
  -  `mounted` ：元素被插入到 DOM 后调用。
  -  `beforeUpdate` ：在元素更新之前调用。
  -  `updated` ：在元素更新后调用。
  -  `beforeUnmount` ：在元素被卸载之前调用。
  -  `unmounted` ：元素被卸载后调用。

  4. 传递参数和修饰符
  自定义指令可以接收参数和修饰符，以便实现更灵活的功能。

   示例：传递参数
  app.directive('color', {
    mounted(el, binding) {
      el.style.color = binding.value; // 使用传递的颜色值
    }
  });
   使用示例：
  vue
  <template>
    <p v-color="'red'">This text is red.</p>
  </template>
   示例：使用修饰符
  app.directive('text', {
    mounted(el, binding) {
      el.textContent = binding.value.toUpperCase(); // 将文本转换为大写
    }
  });
   使用示例：
  vue
  <template>
    <p v-text.uppercase="'hello'">This text will be uppercase.</p>
  </template>
  5. 总结
  自定义指令是 Vue 3 中一个强大的特性，允许开发者对 DOM 元素进行更细粒度的控制。通过注册自定义指令，开发者可以实现特定的功能和行为，增强应用的灵活性和可扩展性。理解自定义指令的创建和使用方法，可以帮助开发者更好地利用 Vue 3 的功能，提高开发效率。 
-->
<!-- options ap自定义 -->
<!-- <script>
  export default {
    directives: {
      focus: {
        // 生命周期的函数(自定义指令)
        mounted(el) {
          // console.log("v-focus应用的元素被挂载了", el)
          el?.focus()
        }
      }
    }
  }
</script> -->
<template>
  <div class="app">
    <h3>1. 自定义指令基本使用</h3>
    <input type="text" v-focus>
    <div v-ftime="'YYYY-MM-DD'">{{ 1551111166666 }}</div>

    <h3>2. 自定义指令生命周期</h3>
    <button @click="counter++">+1</button>
    <button @click="showTitle = false">隐藏</button>
    <div v-if="showTitle" class="title" v-directive-lite-cycle>当前计数: {{ counter }}</div>

    <h3>3. 自定义指令参数修饰符</h3>
    <p v-directive-modifiers.uppercase="'hello '">This text will be uppercase.</p>
    <p v-directive-modifiers.lowercase="'hello '">This text will be uppercase.</p>

    
  </div>
</template>

<script setup>
  import { ref } from 'vue';
  const counter = ref(0)
  const showTitle = ref(true)

  // 1.方式一: 定义ref绑定到input中, 调用focus
  // import useInput from "./hooks/useInput"
  // const { inputRef } = useInput()

  // 2.方式二: 自定义指令(局部指令)
  // const vFocus = {
  //   // 生命周期的函数(自定义指令)
  //   mounted(el) {
  //     // console.log("v-focus应用的元素被挂载了", el)
  //     el?.focus()
  //   }
  // }

  // 3. 自定义指令生命周期
  const vDirectiveLiteCycle = {
    created() {
      console.log("v-directivelite-cycle created: 元素初始化的时候，还没有挂载到DOM，但是模板已经处理");
    },
    beforeMounted() {
      console.log("v-directivelite-cycle beforeMounted: 元素挂载到DOM之前");
    },
    mounted() {
      console.log("v-directivelite-cycle mounted: 元素挂载到DOM上之后");
    },
    beforeUpdate() {
      console.log("v-directivelite-cycle beforeUpdate: 元素更新之前");
    },
    updated() {
      console.log("v-directivelite-cycle updated: 元素更新完成之后");
    },
    beforeUnmount() {
      console.log("v-directivelite-cycle beforeUnmount: 元素卸载之前");
    },
    unmounted() {
      console.log("v-directivelite-cycle unmounted: 元素卸载之后");
    }
  }

  // 4. 自定义指令修饰符
  const vDirectiveModifiers = {
    mounted(el, binding) {
      console.log("v-directive-modifiers mounted: 元素挂载到DOM上之后", el, binding)
      if (binding.modifiers.uppercase) {
        el.textContent = binding.value + el.textContent.toUpperCase()
      }
      if (binding.modifiers.lowercase) {
        el.textContent = binding.value + el.textContent.toLowerCase()
      }
    }
  }


</script>

<style lang="scss" scoped></style>
